package com.xxx.mch.service.impl;

import com.xxx.mch.dao.UsedScoreTemplateMapper;
import com.xxx.mch.domain.dto.UsedScoreTemplateDto;
import com.xxx.mch.domain.po.TaskScoreTemplate;
import com.xxx.mch.domain.po.UsedScoreTemplate;
import com.xxx.mch.domain.request.RuleSearchRequest;
import com.xxx.mch.domain.request.UsedScoreTemplateRequest;
import com.xxx.mch.exception.BusinessException;
import com.xxx.mch.service.UsedScoreService;
import javax.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author FengHaixin
 * @description 一句话描述该文件的用途
 * @date 2020-10-12
 */
@Service
public class UsedScoreServiceImpl implements UsedScoreService
{

    @Resource
    private UsedScoreTemplateMapper usedScoreTemplateMapper;


    @Override
    public void createOrUpdateTemplate(List<UsedScoreTemplateRequest> templateRequestList)
    {
        if (CollectionUtils.isEmpty(templateRequestList))
        {
            return;
        }

        templateRequestList.forEach(this::doCreateOrUpdateTemplate);
    }


    @Override
    public void deleteTemplate(Integer templateId)
    {
        List<UsedScoreTemplate> templateList = usedScoreTemplateMapper.select(new UsedScoreTemplate().setParentId(templateId));
        if (!CollectionUtils.isEmpty(templateList))
        {
            throw new BusinessException("该菜单下还有子菜单，请先删除子菜单");
        }
        usedScoreTemplateMapper.deleteByPrimaryKey(templateId);
    }


    @Override
    public List<UsedScoreTemplateDto> getTaskTemplate(List<Integer> parentId, Integer depth, Boolean status)
    {
        //先查询根，parentId是空的
        Weekend<UsedScoreTemplate> weekend = new Weekend<>(UsedScoreTemplate.class);
        WeekendCriteria<UsedScoreTemplate, Object> criteria = weekend.weekendCriteria();

        if (CollectionUtils.isEmpty(parentId))
        {
            criteria.andIsNull(UsedScoreTemplate::getParentId);
        }
        else
        {
            criteria.andIn(UsedScoreTemplate::getId, parentId);
        }
        List<UsedScoreTemplate> templates = usedScoreTemplateMapper.selectByExample(weekend);
        List<UsedScoreTemplateDto> taskScoreTemplateDtoList = this.convert(templates);
        this.querySubContext(taskScoreTemplateDtoList, --depth, status);
        return taskScoreTemplateDtoList;
    }


    @Override
    public List<UsedScoreTemplateDto> ruleSearch(RuleSearchRequest ruleSearchRequest)
    {
        Weekend<UsedScoreTemplate> weekend = new Weekend<>(UsedScoreTemplate.class);
        WeekendCriteria<UsedScoreTemplate, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(UsedScoreTemplate::getParentId, ruleSearchRequest.getParentId());
        criteria.andLike(UsedScoreTemplate::getName, "%" + ruleSearchRequest.getName() + "%");
        return this.convert(usedScoreTemplateMapper.selectByExample(weekend));
    }


    private void querySubContext(List<UsedScoreTemplateDto> templates, Integer depth, Boolean status)
    {
        //终止条件
        if (CollectionUtils.isEmpty(templates) || depth <= 0)
        {
            return;
        }

        for (UsedScoreTemplateDto usedScoreTemplateDto : templates)
        {
            List<UsedScoreTemplate> subContextList = usedScoreTemplateMapper.select(
                    new UsedScoreTemplate().setParentId(usedScoreTemplateDto.getId()).setStatus(status));
            //设置为下一级
            List<UsedScoreTemplateDto> taskScoreTemplateDtoList = this.convert(subContextList);
            usedScoreTemplateDto.setChildren(taskScoreTemplateDtoList);
            this.querySubContext(taskScoreTemplateDtoList, --depth, status);
            ++depth;
        }
    }


    private List<UsedScoreTemplateDto> convert(List<UsedScoreTemplate> templates)
    {
        return templates.stream().map(usedScoreTemplate -> {
            UsedScoreTemplateDto templateDto = new UsedScoreTemplateDto();
            BeanUtils.copyProperties(usedScoreTemplate, templateDto);
            return templateDto;
        }).collect(Collectors.toList());
    }


    private void doCreateOrUpdateTemplate(UsedScoreTemplateRequest templateRequest)
    {
        UsedScoreTemplate template = new UsedScoreTemplate();
        BeanUtils.copyProperties(templateRequest, template);

        if (this.isCreate(templateRequest))
        {
            this.doCreate(template);
        }
        else
        {
            this.doUpdate(template);
        }

        List<UsedScoreTemplateRequest> subContext = templateRequest.getChildren();
        if (CollectionUtils.isEmpty(subContext))
        {
            return;
        }
        subContext.forEach(taskScoreTemplate -> {
            taskScoreTemplate.setParentId(template.getId());
            this.doCreateOrUpdateTemplate(taskScoreTemplate);
        });

    }


    private void doUpdate(UsedScoreTemplate template)
    {
        usedScoreTemplateMapper.updateByPrimaryKeySelective(template);

    }


    private void doCreate(UsedScoreTemplate template)
    {
        template.setStatus(true);
        usedScoreTemplateMapper.insertSelective(template);
    }


    private boolean isCreate(UsedScoreTemplateRequest templateRequest)
    {
        return Objects.isNull(templateRequest.getId());
    }
}